<?php


namespace RedMVC\Form\Element;
use RedMVC;
use RedMVC\Form\Validator;

/**
 * AElement class
 *  
 * @category    RedMVC
 * @package     Form
 * @subpackage  Element 
 * @author      Jan Fischer, bitWorking <info@bitworking.de>
 */
abstract class AElement{
    
    protected $form                 = null;
    
    protected $varname              = null;
    protected $value                = null;
    protected $label                = null;
    protected $description          = null;    
    
    protected $validators           = array();
    protected $filters              = array();
    protected $attributes           = array();
    protected $errors               = array();
    
    protected $required             = false;
    protected $labelSign            = ':';
    protected $labelRequiredSign    = '*';
    
    protected $template             = '
        <tr>
            <td valign="top"><span class="formLabel">{label}{labelSign}{labelRequiredSign}</span></td>
            <td>{element}<div class="formErrors">{errors}</div></td>
            <td valign="top"><div class="formDescription" title="{description}">{descriptionSign}</div></td>
        </tr>
    ';

    abstract public function render();

    public function __construct($varname){
        $this->setVarname($varname);
    }
    
    public function setForm(RedMVC\Form $form){
        $this->form = $form;
        return $this;
    }
    
    public function setVarname($varname){
        $this->varname = $varname;
        return $this;
    }
    
    public function getVarname(){
        return $this->varname;
    }
    
    public function setValue($value){
        $this->value = $value;
        return $this;
    }
    
    public function getValue(){
        if($this->form->hasErrors() || $this->form->getKeepValues()){
            return $this->form->getRequestValue($this->getVarname());
        }
        return $this->value;
    }
    
    public function setLabel($label){
        $this->label = $label;
        return $this;
    }
    
    public function getLabel(){
        return $this->label;
    }
    
    public function setDescription($description){
        $this->description = $description;
        return $this;
    }
    
    public function getDescription(){
        return htmlentities($this->description, ENT_QUOTES, 'UTF-8');
    }
    
    public function setTemplate($template){
        $this->template = $template;
        return $this;
    }
    
    public function getTemplate(){
        return $this->template;
    }
    
    protected function preRender(){
        if($this->required){            
            array_unshift($this->validators, new RedMVC\Form\Validator\NotEmpty());
        }
    }
    
    public function getTemplateVars(){
        $translate = RedMVC\Registry::get('RedMVC_Translate');
    
        $vars = array(
            '{label}'               => $translate->_($this->getLabel()),
            '{labelSign}'           => $this->getLabelSign(),
            '{labelRequiredSign}'   => $this->getLabelRequiredSign(),
            '{element}'             => $this->render(),
            '{errors}'              => $this->renderErrors(),
            '{description}'         => $translate->_($this->getDescription()),
        );
        
        if(null !== $this->description && !empty($this->description)){
            $vars['{descriptionSign}'] = $this->form->getDescriptionSign();
        }
        else{
            $vars['{descriptionSign}'] = '';
        }
        
        return $vars;
    }
    
    public function setAttributes(array $attributes){
        $this->attributes = $attributes;
        return $this;
    }
    
    public function addAttribute($attribute, $value){
        $this->attributes[$attribute] = $value;
        return $this;
    }
    
    public function addValidator(RedMVC\Form\Validator\AValidator $validator){
        $this->validators[] = $validator;
        return $this;
    }
    
    public function getValidators(){
        $this->preRender();
        return $this->validators;
    }
    
    public function addFilter(RedMVC\Form\Filter\AFilter $filter){
        $this->filters[] = $filter;
        return $this;
    }
    
    public function getFilters(){        
        return $this->filters;
    }
    
    public function addError($error){
        $this->errors[] = $error;
        $this->form->setError(true);
        return $this;
    }
    
    public function getErrors(){
        return $this->errors;
    }
    
    public function renderErrors(){
        if(count($this->errors) == 0){
            return '';
        }    
        $out = '<div><ul>';
        foreach($this->errors as $error){
            $out .= '<li>'.$error.'</li>';
        }        
        $out .= '</ul></div>';
        return $out;
    }
    
    public function setRequired($required){
        $this->required = (bool) $required;
        return $this;
    }
    
    public function isRequired(){
        return $this->required;
    }
    
    public function setLabelSign($labelSign){
        $this->labelSign = $labelSign;
        return $this;
    }
    
    public function getLabelSign(){
        if(!empty($this->label)){
            return $this->labelSign;
        }
        return '';
    }
    
    public function setLabelRequiredSign($labelRequiredSign){
        $this->labelRequiredSign = $labelRequiredSign;
        return $this;
    }
    
    public function getLabelRequiredSign(){
        if($this->required && !empty($this->label)){
            return $this->labelRequiredSign;
        }
        return '';
    }
    
}